package pers.xiaojun.boot.module.infra.controller.file;

import cn.hutool.core.io.IoUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import pers.xiaojun.boot.common.pojo.CommonResult;
import pers.xiaojun.boot.common.pojo.PageResult;
import pers.xiaojun.boot.module.infra.controller.file.vo.file.*;
import pers.xiaojun.boot.module.infra.service.file.FileService;
import pers.xiaojun.boot.mybatis.core.convert.PageConvert;
import pers.xiaojun.boot.web.core.annotation.AdminApi;

import java.io.IOException;
import java.util.Set;

/**
 * 文件控制层
 *
 * @author xiaojun
 * @since 2025-11-13
 */
@Tag(name = "文件")
@AdminApi
@RestController
@RequestMapping("/infra/file")
@RequiredArgsConstructor
public class FileController {

    private final FileService fileService;

    @PostMapping
    @PreAuthorize("@ss.hasPermission('infra:file:create')")
    @Operation(summary = "创建文件信息")
    public CommonResult<?> createFile(@Valid @RequestBody FileSaveReqVO createVO) {
        return CommonResult.success(fileService.saveFile(createVO).getId());
    }

    @GetMapping("/page")
    @PreAuthorize("@ss.hasPermission('infra:file:query')")
    @Operation(summary = "获取文件分页")
    public CommonResult<PageResult<FileRespVO>> getFilePage(@Valid FileQueryReqVO queryVO) {
        return CommonResult.success(PageConvert.INSTANCE.toPageResult(fileService.listFilesPage(queryVO), FileRespVO.class));
    }

    @GetMapping("/presigned-url")
    @Operation(summary = "获取文件预签名地址")
    @Parameters({
            @Parameter(name = "filename", description = "文件名称", required = true),
            @Parameter(name = "directory", description = "文件目录")
    })
    public CommonResult<FilePresignedUrlRespVO> getPresignedPutObjectUrl(
            @RequestParam("name") String filename,
            @RequestParam(value = "directory", required = false) String directory) {

        return CommonResult.success(fileService.getFilePresignedUrl(directory, filename));
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("@ss.hasPermission('infra:file:delete')")
    @Operation(summary = "删除文件")
    @Parameter(name = "Id", description = "文件Id", required = true, example = "1")
    public CommonResult<?> deleteFile(@PathVariable("id") Long fileId) {
        fileService.removeFileById(fileId);
        return CommonResult.success();
    }

    @DeleteMapping("/batch/{ids}")
    @PreAuthorize("@ss.hasPermission('infra:file:delete')")
    @Operation(summary = "删除一批文件")
    @Parameter(name = "ids", description = "文件Id列表", required = true, example = "1,2,3")
    public CommonResult<?> deleteFileBatch(@PathVariable("ids") Set<Long> fileIds) {
        fileService.removeFileByIds(fileIds);
        return CommonResult.success();
    }

    @PostMapping("/upload")
    @Operation(summary = "上传文件")
    public CommonResult<?> uploadFile(FileUploadReqVO uploadReqVO) throws IOException {
        MultipartFile file = uploadReqVO.getFile();
        byte[] content = IoUtil.readBytes(file.getInputStream());
        return CommonResult.success(fileService.uploadFile(content, file.getOriginalFilename(),
                uploadReqVO.getDirectory(), file.getContentType()));
    }

}
